//
//  BBImageDecoder.swift
//  BBImageDecoder
//
//  Created by YouMao on 2022/5/6.
//

import Foundation

public struct BBImageDecoder {
    
}

// MARK: - 核心图像的渲染器重新渲染
extension BBImageDecoder {
    /// 核心图像渲染器重新渲染图片大小
    @available (iOS 10.0, *)
    public static func rerender(at view: UIView, to size: CGSize) -> UIImage? {
        let render = UIGraphicsImageRenderer(size: size)
        return render.image { [weak view] context in
            view?.draw(CGRect(x: 0, y: 0, width: size.width, height: size.height))
        }
    }
}

// MARK: - 向下采样
extension BBImageDecoder {
    
    /// 图片向下采集配置
    static func downsampleOpthons(_ pixels: CGFloat) -> CFDictionary {
        return [
            // · kCGImageSourceCreateThumbnailFromImageAlways
            //这个选项控制是否生成缩略图（没有设为true的话 kCGImageSourceThumbnailMaxPixelSize 以及 CGImageSourceCreateThumbnailAtIndex不会起作用）默认为false，所以需要设置为true
            kCGImageSourceCreateThumbnailFromImageAlways: true,
            // · kCGImageSourceShouldCacheImmediately
            // 是否在创建图片时就进行解码（当然要这么做，避免在渲染时解码占用cpu）并缓存，
            /* Specifies whether image decoding and caching should happen at image creation time.
            * The value of this key must be a CFBooleanRef. The default value is kCFBooleanFalse (image decoding will
            * happen at rendering time).
             //默认为不缓存，在图片渲染时进行图片解码
            */
            kCGImageSourceShouldCacheImmediately: true,
            // · kCGImageSourceCreateThumbnailWithTransform
            //指定是否应根据完整图像的方向和像素纵横比旋转和缩放缩略图
            /* Specifies whether the thumbnail should be rotated and scaled according
             * to the orientation and pixel aspect ratio of the full image.（默认为false
             */
            kCGImageSourceCreateThumbnailWithTransform: true,
            
            // · kCGImageSourceThumbnailMaxPixelSize
            /* Specifies the maximum width and height in pixels of a thumbnail.  If
             * this this key is not specified, the width and height of a thumbnail is
             * not limited and thumbnails may be as big as the image itself.  If
             * present, this value of this key must be a CFNumberRef. */
            kCGImageSourceThumbnailMaxPixelSize:pixels
        ] as CFDictionary
    }
    
    static var imageSourcesOption: CFDictionary {
        get {
            return [kCGImageSourceShouldCache: false] as CFDictionary
        }
    }
    
    /// 图片向下采样
    public static func downsample(imageAt data: Data, to pointSize: CGSize, scale: CGFloat = 1.0) -> UIImage? {
 
        guard let imageSource = CGImageSourceCreateWithData(data as CFData, imageSourcesOption) else {
            return nil
        }
        
        return downsample(imageAt: imageSource, to: pointSize, scale: scale)
    }
    
    /// 图片向下采样
    public static func downsample(imageAt url: URL, to pointSize: CGSize, scale: CGFloat = 1.0) -> UIImage? {
        
        guard let imageSource = CGImageSourceCreateWithURL(url as CFURL, imageSourcesOption) else {
            return nil
        }
        
        return downsample(imageAt: imageSource, to: pointSize, scale: scale)
    }
    
    /// 图片向下采样
    public static func downsample(imageAt imageSource: CGImageSource, to pointSize: CGSize, scale: CGFloat = 1.0) -> UIImage? {
        
        let maxDimensionInPixels = max(pointSize.width, pointSize.height) * scale
        
        let downsampleOptions = downsampleOpthons(maxDimensionInPixels)
        
        guard let downsmpleImage = CGImageSourceCreateThumbnailAtIndex(imageSource, 0, downsampleOptions) else {
            return nil
        }
        let image = UIImage(cgImage: downsmpleImage)
        
        return image
    }
    
}
